function f = geteigpreserve(cri, v)
%GETPCAPRESERVE Gets the function handle for eigenvalue preservation
%
% [ Syntax ]
%   - f = geteigpreserve(cri, v)
%
% [ History ]
%   - Created by Dahua Lin, on Jul 16, 2007
%

%% parse and verify input arguments

assert(ischar(cri), 'sltoolbox:geteigpreserve:invalidarg', ...
    'The first argument of preserve option should be a string.');

switch cri
    case 'rank'
        f = @(evals) 1 : sum(evals > eps(evals(1)));
        
    case 'num'
        assert(isnumeric(v) && isscalar(v) && v >= 1 && v == fix(v), ...
            'sltoolbox:geteigpreserve:invalidarg', ...
            'The parameter for num criteria should be a positive integer scalar.');
        f = @(evals) 1 : min(v, length(evals));
        
    case 'ratio'
        assert(isnumeric(v) && isreal(v) && isscalar(v) && v > 0 && v < 1, ...
            'sltoolbox:geteigpreserve:invalidarg', ...
            'The parameter for ratio criteria should be a real scalar between 0 and 1');
        f = @(evals) 1 : sum(evals >= v * evals(1));
        
    case 'energy'
        assert(isnumeric(v) && isreal(v) && isscalar(v) && v > 0 && v < 1, ...
            'sltoolbox:geteigpreserve:invalidarg', ...
            'The parameter for ratio criteria should be a real scalar between 0 and 1');
        f = @(evals) 1 : find(cumsum(evals) >= v * sum(evals), 1);
        
    otherwise
        error('Unknown criteria for eigenvalue preservation: %s', cri);
end